home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / jwpsrc.zip / REFORMAT.C < prev    next >
C/C++ Source or Header  |  1993-03-31  |  19KB  |  731 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4.  
  5. BOOL NullParaFormatProc(FILEOPTIONS *f, PARAGRAPH far *pp, int n);
  6.  
  7. static UNIT far *CurrentPosition, far *TopPosition;
  8. static POSITION StopPos;
  9. static long int OldBottom;
  10.  
  11. static BOOL TopChanged;
  12. static BOOL (* NewParaFormatProc)(FILEOPTIONS *, PARAGRAPH far *, int) = NullParaFormatProc;
  13. static int nr_para = 0;
  14.  
  15.  
  16.  
  17. static BOOL NullParaFormatProc(FILEOPTIONS *f, PARAGRAPH far *pp, int n)
  18. {
  19.     return (TRUE);
  20. }
  21.  
  22.  
  23.  
  24. void SetReformatProc (BOOL (*f_pf)(FILEOPTIONS *, PARAGRAPH far *, int))
  25. {
  26.     if (f_pf == NULL) NewParaFormatProc = NullParaFormatProc;
  27.     else NewParaFormatProc = f_pf;
  28. }
  29.  
  30.  
  31.  
  32. static void SplitLine (FILEOPTIONS *f, POSITION p, int Options)
  33. {
  34.     int i, j, len;
  35.     unsigned int n;
  36.     PARAGRAPH far *pp;
  37.     ONELINE far *lp;
  38.  
  39.  
  40.     /* How many blocks needed? */
  41.  
  42.     len = unitlen(&UNITOF(p, POSOF(p)+1)) + 1;
  43.     n = len / TEXTBLOCKSIZE;
  44.     n = (n + 1) * TEXTBLOCKSIZE;
  45.  
  46.     pp = StructAlloc(PARAGRAPH);
  47.  
  48.     pp->leftindent = PARAOF(p)->leftindent;
  49.     pp->rightindent = PARAOF(p)->rightindent;
  50.     pp->firstindent = PARAOF(p)->firstindent;
  51.     pp->spacing = PARAOF(p)->spacing;
  52.     pp->spacemulti = PARAOF(p)->spacemulti;
  53.  
  54.     pp->prev = PARAOF(p);
  55.     pp->next = PARAOF(p)->next;
  56.     PARAOF(p)->next = pp;
  57.  
  58.     if (pp->next != NULL) pp->next->prev = pp;
  59.     else f->eof = pp;
  60.  
  61.  
  62.     pp->textsize = n;
  63.  
  64.     lp = pp->lines = pp->lastline = StructAlloc(ONELINE);
  65.     f->nr_lines++;
  66.  
  67.     lp->prev = lp->next = NULL;
  68.  
  69.     lp->position = 0;
  70.     pp->text = (UNIT far *) BlockAlloc(n * sizeof(UNIT));
  71.  
  72.     lp->length = len;
  73.     lp->height = lp->width = 0;
  74.  
  75.  
  76.     /* Copy the text */
  77.  
  78.     for (i = 0, j = POSOF(p) + 1; ; i++, j++) {
  79.         if (Options & OP_MOVESEL) {
  80.             if (SELPARA1(f) == PARAOF(p) && &UNITOF(p, j) == &SELCHAR1(f)) {
  81.                 SELPARA1(f) = pp;
  82.                 SELPOS1(f) = i;
  83.             }
  84.             if (SELPARA2(f) == PARAOF(p) && &UNITOF(p, j) == &SELCHAR2(f)) {
  85.                 SELPARA2(f) = pp;
  86.                 SELPOS2(f) = i;
  87.             }
  88.         }
  89.  
  90.         if (&UNITOF(f->current,CURCHAR(f)) == &UNITOF(p, j)) {
  91.             CURPARA(f) = pp;
  92.             CURLINE(f) = lp;
  93.             CURCHAR(f) = i;
  94.         }
  95.         if (CurrentPosition == &UNITOF(p, j)) CurrentPosition = &(pp->text[i]);
  96.         if (TopPosition == &UNITOF(p, j)) {
  97.             TopPosition = &(pp->text[i]);
  98.             TopChanged = (j != 0);
  99.         }
  100.  
  101.         pp->text[i] = UNITOF(p,j);
  102.         if (!CHAROF(p, j)) break;
  103.     }
  104.  
  105.  
  106.     PARAOF(p)->lastline = LINEOF(p);
  107.     LINEOF(p)->length = POSOF(p);
  108.     CHAROF(p, POSOF(p)) = 0;
  109.  
  110.     f->nr_bytes--;
  111.  
  112.     ReallocateText(p, unitlen(PARAOF(p)->text));
  113.  
  114.     /* Special format? */
  115.  
  116.     NewParaFormatProc(f, pp, nr_para + 1);
  117. }
  118.  
  119.  
  120.  
  121. static void JoinLine (FILEOPTIONS *f, POSITION p, int Options)
  122. {
  123.     int i, j;
  124.     PARAGRAPH far *pp;
  125.     ONELINE far *tp1, far *tp2;
  126.  
  127.  
  128.     /* Join with the next paragraph */
  129.  
  130.     pp = PARAOF(p)->next;
  131.     if (pp->next == NULL && pp == f->eof) f->eof = PARAOF(p);
  132.  
  133.  
  134.     /* Do we need to shift the next paragraph's margins up? */
  135.  
  136.     if (POSOF(p) <= 0) {
  137.         PARAOF(p)->firstindent = pp->firstindent;
  138.         PARAOF(p)->leftindent = pp->leftindent;
  139.         PARAOF(p)->rightindent = pp->rightindent;
  140.     }
  141.  
  142.  
  143.     /* How many blocks needed? */
  144.  
  145.     ReallocateText (p, unitlen(pp->text) + unitlen(PARAOF(p)->text) + 1);
  146.  
  147.     CurrentPosition = &UNITOF(f->current,CURCHAR(f));
  148.     TopPosition = TOPPARA(f)->text + TOPLINE(f)->position;
  149.  
  150.  
  151.     /* Is the cursor on the remaining text? */
  152.  
  153.     for (i = POSOF(p) + 1; ; i++) {
  154.         if (CurrentPosition == &UNITOF(p,i)) {
  155.             CurrentPosition = &UNITOF(p,POSOF(p));
  156.             break;
  157.         } else if (!CHAROF(p,i)) break;
  158.     }
  159.  
  160.  
  161.     /* Copy the text */
  162.  
  163.     for (i = 0, j = POSOF(p); ; i++, j++) {
  164.         if (Options & OP_MOVESEL) {
  165.             if (SELPARA1(f) == pp && &(pp->text[i]) == &SELCHAR1(f)) {
  166.                 SELPARA1(f) = PARAOF(p);
  167.                 SELPOS1(f) = LINEOF(p)->position + j;
  168.             }
  169.             if (SELPARA2(f) == pp && &(pp->text[i]) == &SELCHAR2(f)) {
  170.                 SELPARA2(f) = PARAOF(p);
  171.                 SELPOS2(f) = LINEOF(p)->position + j;
  172.             }
  173.         }
  174.  
  175.         if (CurrentPosition == pp->text + i) CurrentPosition = &UNITOF(p, j);
  176.         if (TopPosition == pp->text + i) {
  177.             TopPosition = &UNITOF(p, j);
  178.             TopChanged = (j != 0);
  179.         }
  180.  
  181.         UNITOF(p,j) = pp->text[i];
  182.         if (!CHAROF(p, j)) break;
  183.     }
  184.  
  185.  
  186.     PARAOF(p)->lastline = LINEOF(p);
  187.     LINEOF(p)->length = j;
  188.  
  189.  
  190.     /* Re-link */
  191.  
  192.     PARAOF(p)->next = pp->next;
  193.     if (pp->next != NULL) pp->next->prev = PARAOF(p);
  194.  
  195.     PARAOF(StopPos) = pp->next;
  196.     LINEOF(StopPos) = (pp->next != NULL) ? pp->next->lines : NULL;
  197.     POSOF(StopPos) = 0;
  198.  
  199.  
  200.     /* Gets rid of the next paragraph */
  201.  
  202.     for (tp1 = pp->lines; tp1 != NULL; ) {
  203.         tp2 = tp1;
  204.         tp1 = tp1->next;
  205.         OldBottom += tp2->height + pp->spacing;
  206.         FreeStruct(tp2);
  207.         f->nr_lines--;
  208.     }
  209.  
  210.     if (pp->text != NULL) FreeBlock(pp->text);
  211.     FreeStruct(pp);
  212.  
  213.     f->nr_bytes--;
  214. }
  215.  
  216.  
  217.  
  218. static BOOL IsWhiteSpace (KANJI ch)
  219. {
  220.     if (ch <= ' ') return (TRUE);
  221.     return (FALSE);
  222. }
  223.  
  224.  
  225.  
  226. static BOOL IsWordWrap (POSITION *p)
  227. {
  228.     int i;
  229.     KANJI ch;
  230.     UNIT far *cp = &UNITOF(*p, POSOF(*p));
  231.  
  232.     ch = cp->kanji;
  233.  
  234.     if (ISKANJI(ch)) return (FALSE);
  235.     if (IsWhiteSpace(ch)) return (FALSE);
  236.  
  237.     /* Back-seek */
  238.  
  239.     for (i = POSOF(*p); i >= 0; i--, cp--) {
  240.         ch = cp->kanji;
  241.         if (ISKANJI(ch) || IsWhiteSpace(ch) || ch == '-') break;
  242.     }
  243.  
  244.     if (i < 0) return (FALSE);      /* Word longer than one line! */
  245.  
  246.     POSOF(*p) = i + 1;
  247.     return (TRUE);
  248. }
  249.  
  250.  
  251.  
  252. static BOOL PotentialWordWrap (POSITION p)
  253. {
  254.     int i;
  255.     KANJI ch;
  256.     UNIT far *cp = &UNITOF(p, POSOF(p));
  257.  
  258.     if (ISKANJI(cp->kanji)) {
  259.         if (POSOF(p) == 0) return (TRUE);
  260.         return (FALSE);
  261.     }
  262.  
  263.     /* Skip white spaces */
  264.  
  265.     for (i = POSOF(p); i > 0; i--, POSOF(p)--, cp--) {
  266.         ch = cp->kanji;
  267.         if (ISKANJI(ch)) return (FALSE);
  268.         if (!IsWhiteSpace(ch)) break;
  269.     }
  270.  
  271.     if (i < 0) return (FALSE);
  272.  
  273.     /* Now, is this word alone? */
  274.  
  275.     return (!IsWordWrap(&p));
  276. }
  277.  
  278.  
  279.  
  280. static BOOL OpenNewLine (FILEOPTIONS *f, POSITION p, int width, int height, int length)
  281. {
  282.     UNIT far *cp = &UNITOF(p,POSOF(p));
  283.     BOOL CanStop = FALSE;
  284.  
  285.     if (LINEOF(p)->next == NULL) {
  286.         LINEOF(p)->next = StructAlloc(ONELINE);
  287.         LINEOF(p)->next->prev = LINEOF(p);
  288.         LINEOF(p)->next->next = NULL;
  289.         LINEOF(p)->next->position = 0;
  290.         f->nr_lines++;
  291.     } else {
  292.         if (POS2ABS(p) == LINEOF(p)->next->position) CanStop = TRUE;
  293.     }
  294.  
  295.     LINEOF(p)->height = height;
  296.     LINEOF(p)->width = width;
  297.     LINEOF(p)->length = length;
  298.  
  299.     LINEOF(p) = LINEOF(p)->next;
  300.     LINEOF(p)->position = cp - PARAOF(p)->text;
  301.     if (!CanStop) LINEOF(p)->length = unitlen(cp);
  302.  
  303.     return (CanStop);
  304. }
  305.  
  306.  
  307.  
  308. void ReformatParagraph (FILEOPTIONS *f, POSITION start, PARAGRAPH far *stop, int options)
  309. {
  310.     int i, j, r, w;
  311.     long int OldTop, NewBottom;
  312.     int BlockHeight = LINEGAP(f);
  313.     int MaxHeight, LineLength;
  314.     long int dimension;
  315.     UNIT far *cp;
  316.     POSITION p;
  317.     RECT rect;
  318.     BOOL GoneBack = FALSE, CanStop;
  319.     BOOL relaxed, SoftReturn;
  320.     HDC hdc, hdcmem;
  321.     HBRUSH hbrush;
  322.     HBITMAP hbitmap;
  323.  
  324.  
  325.     TopChanged = FALSE;
  326.  
  327.     /* Word wrap situation? */
  328.  
  329.     if (PotentialWordWrap(start) && LINEOF(start)->prev != NULL) {
  330.         p = start;
  331.         LINEOF(start) = LINEOF(start)->prev;
  332.         POSOF(start) = LINEOF(start)->length - 1;
  333.  
  334.         GoneBack = TRUE;
  335.     }
  336.  
  337.  
  338.     /* Now take care of some accounting */
  339.  
  340.     CurrentPosition = &UNITOF(f->current,CURCHAR(f));
  341.     TopPosition = &(TOPPARA(f)->text[TOPLINE(f)->position]);
  342.  
  343.     if (stop != NULL) {
  344.         PARAOF(StopPos) = stop;
  345.         LINEOF(StopPos) = stop->lines;
  346.         POSOF(StopPos) = 0;
  347.